/**
 * 
 */
package fr.flogo.destinee.cameras;

import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLU;

import fr.flogo.destinee.positions.Vector3D;

/**
 * @author golestif
 *
 */
public class KaylFreefly implements ICamera {

	
//	-----
	

	private Vector3D _position;
private double _phi;
private double _theta;
private double _speed;
private double _sensivity;
private Vector3D _forward = new Vector3D(0d, 0d, 0d);
private Vector3D _target = new Vector3D(0d, 0d, 0d);;
private double M_PI = 3.14159265d;
private Vector3D _left = new Vector3D(0d, 0d, 0d);;
	
	
	public KaylFreefly(Vector3D position)
	{
	    _position = position;
	    _phi = 0.0d;
	    _theta = 0.0d;
	    VectorsFromAngles();

	    _speed = 0.01d;
	    _sensivity = 0.2d;

	}

	void OnMouseMotion(double xrel, double yrel)
	{
	    _theta -= xrel*_sensivity;
	    _phi -= yrel*_sensivity;
	    VectorsFromAngles();
	}
	

//	void animate(int type)
//	{
////	    double realspeed = (_keystates[_keyconf["boost"]])?10*_speed:_speed;
//	    if (_type == 0)
//	        _position += _forward * (realspeed * timestep);
//	    if (_keystates[_keyconf["backward"]])
//	        _position -= _forward * (realspeed * timestep);
//	    if (_keystates[_keyconf["strafe_left"]])
//	        _position += _left * (realspeed * timestep);
//	    if (_keystates[_keyconf["strafe_right"]])
//	        _position -= _left * (realspeed * timestep);
//	    if (_verticalMotionActive)
//	    {
//	        if (timestep > _timeBeforeStoppingVerticalMotion)
//	            _verticalMotionActive = false;
//	        else
//	            _timeBeforeStoppingVerticalMotion -= timestep;
//	        _position += Vector3D(0,0,_verticalMotionDirection*realspeed*timestep);
//	    }
//	    _target = _position + _forward;
//
//	}

//	void FreeFlyCamera::setSpeed(double speed)
//	{
//	    _speed = speed;
//	}
//
//	void FreeFlyCamera::setSensivity(double sensivity)
//	{
//	    _sensivity = sensivity;
//	}

	void setPosition(Vector3D position)
	{
		// attention
	    _position = (Vector3D) position.clone();
	    position.add(_forward);
	    _target = (Vector3D) position.clone();
	}

	void VectorsFromAngles()
	{
	    final Vector3D up = new Vector3D(0,0,1);
	    
	    if (_phi > 89)
	        _phi = 89;
	    else if (_phi < -89)
	        _phi = -89;
	    double r_temp = Math.cos(_phi*M_PI/180);
	    _forward.setZ(Math.sin(_phi*M_PI/180));
	    _forward.setX(r_temp*Math.cos(_theta*M_PI/180));
	    _forward.setY(r_temp*Math.sin(_theta*M_PI/180));

	    _left = up.crossProduct(_forward);
	    _left.normalize();

	    _target = (Vector3D) _position.clone();
	    _target.add(_forward);
	}

	void look(GL10 gl)
	{
		// attention
	    GLU.gluLookAt(gl, (float)_position.getX(),(float)_position.getY(),(float)_position.getZ(),
	    		(float)_target.getX(),(float)_target.getY(),(float)_target.getZ(),
	              0f,0f,1f);
	}


	
//	-----
	
	
	/* (non-Javadoc)
	 * @see fr.flogo.destinee.cameras.ICamera#translate(javax.microedition.khronos.opengles.GL10, float, float, float)
	 */
	@Override
	public void translate(GL10 gl, float x, float y, float z) {
		Vector3D v = new Vector3D(x, y, z);
		this.setPosition(v);
	}

	/* (non-Javadoc)
	 * @see fr.flogo.destinee.cameras.ICamera#rotation(javax.microedition.khronos.opengles.GL10, float, float, float, float)
	 */
	@Override
	public void rotation(GL10 gl, float angle, float x, float y, float z) {
		
	}

	/* (non-Javadoc)
	 * @see fr.flogo.destinee.cameras.ICamera#getPosition()
	 */
	@Override
	public float[] getPosition() {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)
	 * @see fr.flogo.destinee.cameras.ICamera#turn(float, float, float, float)
	 */
	@Override
	public void turn(float angle, float x, float y, float z) {
		// attention
				this.OnMouseMotion(angle * x, angle * y);
	}

	/* (non-Javadoc)
	 * @see fr.flogo.destinee.cameras.ICamera#move(float, float, float)
	 */
	@Override
	public void move(float x, float y, float z) {

//		_position += _forward * (realspeed * timestep);
//	    if (_keystates[_keyconf["backward"]])
//	        _position -= _forward * (realspeed * timestep);
//	    if (_keystates[_keyconf["strafe_left"]])
//	        _position += _left * (realspeed * timestep);
//	    if (_keystates[_keyconf["strafe_right"]])
//	        _position -= _left * (realspeed * timestep);
		
		
		if (z > 0) {
			Vector3D temp = (Vector3D) _forward.clone();
			temp.multiply(0.1);
			this._position.add(temp);
		} else {
			Vector3D temp = (Vector3D) _forward.clone();
			temp.multiply(0.1);
			this._position.subtract(temp);
		}
		if (x > 0) {
			Vector3D temp = (Vector3D) _left.clone();
			temp.multiply(0.1);
			this._position.add(temp);
		} else {
			Vector3D temp = (Vector3D) _left.clone();
			temp.multiply(0.1);
			this._position.subtract(temp);
		}
		
		_target = (Vector3D) _position.clone();
		_target.add(_forward);
		
	}

	@Override
	public void drawMovement(GL10 gl) {
		this.look(gl);
	}

}
